#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
#include <QMessageBox>
#include <QTcpSocket>
#include <QListWidget>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置标题
    this->setWindowTitle("服务端");

    // 实例化TcpServer
    server = new QTcpServer(this);

    // 通过信号槽，指定如何处理连接
    connect(server,&QTcpServer::newConnection,this,&Widget::processConnection);

    // 监听端口
    int ret = server->listen(QHostAddress::Any,9090);
    if(!ret)
    {
        QMessageBox::critical(nullptr,"服务器启动失败",server->errorString());
        return;
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::processConnection()
{
    // 获取新连接对应的socket
    QTcpSocket* clientsocket = server->nextPendingConnection();
    // peerAddress：对端地址，即客户端地址
    // peerPort：对端端口号，即客户端端口号
    QString log = QString("[") + clientsocket->peerAddress().toString()
                    + ":" + QString::number(clientsocket->peerPort())
                    + "] 客户端上线";
    ui->listWidget->addItem(log);

    // 通过信号槽处理客户端发来的请求
    connect(clientsocket,&QTcpSocket::readyRead,this,[=](){
        // 1. 读出请求数据
        QString request = clientsocket->readAll();
        // 2. 根据请求处理响应
        const QString& response = process(request);
        // 3. 把响应返回给客户端
        clientsocket->write(response.toUtf8());
        // 4. 将请求和响应记录到日志
        QString log = QString("[") + clientsocket->peerAddress().toString() + ":" + QString::number(clientsocket->peerPort()) + "]"
                        + " req:" + request + "  resp:" + response;
        ui->listWidget->addItem(log);
    });

    // 通过信号槽处理客户端断开的情况
    connect(clientsocket,&QTcpSocket::disconnected,this,[=](){
        // 1. 把连接断开的信息通过日志显示出来
        QString log = QString("[") + clientsocket->peerAddress().toString()
                        + ":" + QString::number(clientsocket->peerPort())
                        + "] 客户端下线";
        ui->listWidget->addItem(log);

        // 2. 手动释放clientsocket
        // 下一轮事件循环再进行销毁
        clientsocket->deleteLater();
    });
}

QString Widget::process(const QString request)
{
    return request;
}

